package com.rfid.api;

import android.annotation.SuppressLint;

import com.rfid.reader.PCReader;
import com.rfid.spec.ISO15693TagDataReport;
import com.rfid.spec.SpecAIPInvenParamISO15693;
import com.rfid.spec.SpecConnPrmsISO15693;
import com.rfid.spec.SpecInvenParamSet;
import com.rfid.spec.SpecTagAccessSet;
import com.rfid.spec.TagOperateHandle;
import com.rfid.spec.tagaccess.SpecDestroy;
import com.rfid.spec.tagaccess.SpecDisableEAS;
import com.rfid.spec.tagaccess.SpecEASCheck;
import com.rfid.spec.tagaccess.SpecEnable64BitsPwd;
import com.rfid.spec.tagaccess.SpecEnableEAS;
import com.rfid.spec.tagaccess.SpecEnablePrivacy;
import com.rfid.spec.tagaccess.SpecGetNxpSysInfo;
import com.rfid.spec.tagaccess.SpecGetRandom;
import com.rfid.spec.tagaccess.SpecGetRandomAndSetPwd;
import com.rfid.spec.tagaccess.SpecGetSysInfor;
import com.rfid.spec.tagaccess.SpecIncrementCounter;
import com.rfid.spec.tagaccess.SpecLockAFI;
import com.rfid.spec.tagaccess.SpecLockDSFID;
import com.rfid.spec.tagaccess.SpecLockEAS;
import com.rfid.spec.tagaccess.SpecLockMultipleBlocks;
import com.rfid.spec.tagaccess.SpecLockPageProtection;
import com.rfid.spec.tagaccess.SpecLockPassword;
import com.rfid.spec.tagaccess.SpecPasswordProtect;
import com.rfid.spec.tagaccess.SpecPresetCounter;
import com.rfid.spec.tagaccess.SpecProtectPage;
import com.rfid.spec.tagaccess.SpecReadMultipleBlocks;
import com.rfid.spec.tagaccess.SpecReadSignature;
import com.rfid.spec.tagaccess.SpecReset;
import com.rfid.spec.tagaccess.SpecSetPassword;
import com.rfid.spec.tagaccess.SpecWriteAFI;
import com.rfid.spec.tagaccess.SpecWriteDSFID;
import com.rfid.spec.tagaccess.SpecWriteEASID;
import com.rfid.spec.tagaccess.SpecWriteMultipleBlocks;
import com.rfid.spec.tagaccess.SpecWritePassword;
import com.rfid.transport.NdkSupport;

public class ISO15693Interface {
    private TagOperateHandle hTag = new TagOperateHandle();
    private PCReader m_reader = null;

    public static SpecAIPInvenParamISO15693 PC_CreateInvenParam(Object hInvenParamSpecList, byte AntennaID, Boolean en_afi, byte afi, byte slot_type) {
        SpecInvenParamSet pInvenParam = (SpecInvenParamSet) hInvenParamSpecList;
        if (pInvenParam == null) return null;
        SpecAIPInvenParamISO15693 iso15693param = SpecAIPInvenParamISO15693.create();
        if (iso15693param == null) return null;
        iso15693param.m_aipType = 1L;
        iso15693param.m_antID = AntennaID;
        iso15693param.m_enableAFI = en_afi.booleanValue();
        iso15693param.m_AFI = afi;
        iso15693param.m_slotType = slot_type;
        pInvenParam.AddAirProtocol(iso15693param);
        return iso15693param;
    }

    public static int PC_ParseTagDataReport(Object hTagReport, Long aip_id, Long tag_id, Long ant_id, Byte dsfid, byte[] uid, Integer uidLen) {
        ISO15693TagDataReport ptdr = null;
        if (hTagReport instanceof ISO15693TagDataReport) ptdr = (ISO15693TagDataReport) hTagReport;
        if (ptdr == null) return -3;
        if (ptdr.m_AIPType != 1L) return -4;
        NdkSupport.SetLongValue(aip_id, ptdr.m_AIPType);
        NdkSupport.SetLongValue(tag_id, ptdr.m_PICCType);
        NdkSupport.SetLongValue(ant_id, ptdr.m_AntID);
        NdkSupport.SetByteValue(dsfid, ptdr.m_dsfid);
        int copyBytes = 8;
        if (uid.length < copyBytes) copyBytes = uid.length;
        System.arraycopy(ptdr.m_uid, 0, uid, 0, copyBytes);
        NdkSupport.SetIntegerValue(uidLen, copyBytes);
        return 0;
    }

    public static int PC_ParseTagDataReport(Object hTagReport, ISO15693Tag tagData) {
        ISO15693TagDataReport ptdr = null;
        if (hTagReport instanceof ISO15693TagDataReport) ptdr = (ISO15693TagDataReport) hTagReport;
        if (ptdr == null) return -3;
        if (ptdr.m_AIPType != 1L) return -4;
        if (tagData == null) return -26;
        tagData.aip_id = ptdr.m_AIPType;
        tagData.tag_id = ptdr.m_PICCType;
        tagData.ant_id = ptdr.m_AntID;
        tagData.dsfid = ptdr.m_dsfid;
        for (int j = 0; j < 8; j++) tagData.uid[j] = ptdr.m_uid[j];
        return 0;
    }

    public static String GetTagNameById(long picc_tid) {
        String tagtype;
        if (picc_tid == 1L) tagtype = "NXP ICODE SLI";
        else if (picc_tid == 2L) tagtype = "Ti HF-I Plus";
        else if (picc_tid == 3L) tagtype = "ST M24LRxx";
        else if (picc_tid == 4L) tagtype = "Fujitsu MB89R118C";
        else if (picc_tid == 5L) tagtype = "ST M24LR64";
        else if (picc_tid == 6L) tagtype = "ST M24LR16E";
        else if (picc_tid == 7L) tagtype = "NXP ICODE SLIX";
        else if (picc_tid == 10L) tagtype = "NXP ICODE SLIX2";
        else if (picc_tid == 8L) tagtype = "Ti HF-I Standard";
        else if (picc_tid == 9L) tagtype = "Ti HF-I Pro";
        else tagtype = "Unknown Tag";
        return tagtype;
    }

    public int PC_Connect(PCReaderInterface hr, long tagType, byte address_mode, byte[] uid) {
        if (hr == null) return 4;
        SpecConnPrmsISO15693 conn_params = ISO15693_CreateConnectParam(tagType, address_mode, uid);
        if (conn_params == null) return -6;
        this.m_reader = hr.GetReader();
        int iret = this.m_reader.PICC_Connect(conn_params, this.hTag);
        if (iret != 0) this.m_reader = null;
        return iret;
    }

    public int PC_Disconnect() {
        if (this.m_reader == null) return 0;
        int iret = this.m_reader.PICC_DisConnect(this.hTag.getTagHandle());
        if (iret == 0) this.hTag.setTagHandle(null);
        return iret;
    }
    @SuppressLint({"UseValueOf"})
    public int PC_ISO15693GetSystemInfo(byte[] uid, byte[] dsfid, byte[] afi, long[] blkSize, long[] numOfBloks, byte[] icRef) {
        /*Byte m_dsfid = new Byte((byte) 0);
        Byte m_afi = new Byte((byte) 0);
        Long m_blkSize = new Long(0L);
        Long m_numOfBloks = new Long(0L);
        Byte m_icRef = new Byte((byte) 0);*/
        int iret = PC_GetSystemInfo(uid, dsfid, afi, blkSize, numOfBloks, icRef);
        if (iret == 0) {
            /*
            dsfid[0] = m_dsfid.byteValue();
            afi[0] = m_afi.byteValue();
            blkSize[0] = m_blkSize.longValue();
            numOfBloks[0] = m_numOfBloks.longValue();
            icRef[0] = m_icRef.byteValue();*/
        }
        return iret;
    }

    public int PC_GetSystemInfo(byte[] uid, byte[] dsfid, byte[] afi, long[] blkSize, long[] numOfBloks, byte[] icRef) {
        if (this.m_reader == null) return -1;
        SpecGetSysInfor tagAccess = ISO15693_CreateTAGetTagInfor(null);
        if (tagAccess == null) return -6;
        int iret = this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
        if (iret != 0) return iret;
        return ISO15693_ParseGetSystemInfoResult(tagAccess, uid, dsfid, afi, blkSize, numOfBloks, icRef);
    }
    public int PC_ReadMultiBlocks(boolean readSecSta, int blkAddr, int numOfBlksToRead, Integer numOfBlksRead, byte[] bufBlocks, Long bytesBlkDatRead) {
        if (this.m_reader == null) return -1;
        SpecReadMultipleBlocks tagAccess = ISO15693_CreateTAReadMultipleBlocks(null, readSecSta, blkAddr, numOfBlksToRead);
        if (tagAccess == null) return -6;
        int iret = this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
        if (iret != 0) return iret;
        Long nCopy = Long.valueOf(bufBlocks.length);
        iret = ISO15693_ParseReadMultiBlocksResult(tagAccess, numOfBlksRead, bufBlocks, nCopy);
        if (bytesBlkDatRead != null) NdkSupport.SetLongValue(bytesBlkDatRead, nCopy.longValue());
        return iret;
    }

    public int PC_WriteMultipleBlocks(int blkAddr, int numOfBlks, byte[] newBlksData) {
        if (this.m_reader == null) return -1;
        SpecWriteMultipleBlocks tagAccess = ISO15693_CreateTAWriteMultipleBlocks(null, blkAddr, numOfBlks, newBlksData, newBlksData.length);
        if (tagAccess == null) return -6;
        int iret = this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
        if (iret != 0) return iret;
        return 0;
    }
    public int PC_LockMultipleBlocks(int blkAddr, int numOfBlks) {
        if (this.m_reader == null) return -1;
        SpecLockMultipleBlocks tagAccess = ISO15693_CreateTALockMultipleBlocks(null, blkAddr, numOfBlks);
        if (tagAccess == null) return -6;
        int iret = this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
        if (iret != 0) return iret;
        return 0;
    }
    public int PC_WriteAFI(byte afi) {
        if (this.m_reader == null) return -1;
        SpecWriteAFI tagAccess = ISO15693_CreateTAWriteAFI(null, afi);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }

    public int PC_LockAFI() {
        if (this.m_reader == null) return -1;
        SpecLockAFI tagAccess = ISO15693_CreateTALockAFI(null);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }
    public int PC_WriteDSFID(byte dsfid) {
        if (this.m_reader == null) return -1;
        SpecWriteDSFID tagAccess = ISO15693_CreateTAWriteDSFID(null, dsfid);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }
    public int PC_LockDSFID() {
        if (this.m_reader == null) return -1;
        SpecLockDSFID tagAccess = ISO15693_CreateTALockDSFID(null);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }
    public int PC_EableEAS() {
        if (this.m_reader == null) return -1;
        SpecEnableEAS tagAccess = NXPICODESLI_CreateTAEableEAS(null);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }
    public int PC_LockEAS() {
        if (this.m_reader == null) return -1;
        SpecLockEAS tagAccess = NXPICODESLI_CreateTALockEAS(null);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }
    public int PC_DisableEAS() {
        if (this.m_reader == null) return -1;
        SpecDisableEAS tagAccess = NXPICODESLI_CreateTADisableEAS(null);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }
    public int PC_EASCheck(Byte EASFlag) {
        if (this.m_reader == null) return -1;
        SpecEASCheck tagAccess = NXPICODESLI_CreateTAEASCheck(null);
        if (tagAccess == null) return -6;
        int iret = this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
        if (iret != 0) return iret;
        return NXPICODESLI_ParseEASCheckResult(tagAccess, EASFlag);
    }
    public int PC_LockPassword(byte pwdNo) {
        SpecLockPassword tagAccess = NXPICODESLI_CreateTALockPassword(null, pwdNo);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }
    public int PC_Enable64BitPwd() {
        SpecEnable64BitsPwd tagAccess = NXPICODESLI_CreateTAEnable64BitPwd(null);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }
    public int PC_GetRandomNum(int[] random) {
        int iret = -1;
        SpecGetRandom tagAccess = NXPICODESLI_CreateTAGetRandaom(null);
        if (tagAccess == null) return -6;
        iret = this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
        if (iret != 0) return iret;
        return NXPICODESLI_ParseGetRandomResult(tagAccess, random);
    }
    public int PC_SetPassword(byte pwdNo, int random, long pwd) {
        if (pwdNo != 16) return -3;
        SpecSetPassword tagAccess = NXPICODESLI_CreateTASetPassword(null, pwdNo, random, pwd);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }
    public int PC_Reset() {
        SpecReset tagAccess = ISO15693_CreateTAReset(null);
        if (tagAccess == null) return -6;
        if (this.m_reader == null)
            return -1;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }
/******************************私有方法***************************************************/
    private static SpecWriteMultipleBlocks ISO15693_CreateTAWriteMultipleBlocks(SpecTagAccessSet hTagAccessSet, int blkAddr, int numOfBlks, byte[] newBlksData, int bytesToWrite) {
        SpecWriteMultipleBlocks p = SpecWriteMultipleBlocks.Create();
        if (p != null) {
            p.m_reqStartBlock = blkAddr;
            p.m_reqNumOfBlockToWrite = numOfBlks;
            p.m_reqBlocksData.WriteData(newBlksData, 0, bytesToWrite);
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    private static int ISO15693_ParseReadMultiBlocksResult(SpecReadMultipleBlocks tagAccess, Integer numOfBlksRead, byte[] bufBlocks, Long nSize) {
        SpecReadMultipleBlocks p = tagAccess;
        if (p == null) return -3;
        if (numOfBlksRead != null) NdkSupport.SetIntegerValue(numOfBlksRead, p.m_respNumRead);
        int byReaded = p.m_respBlocksData.ReadData(bufBlocks, nSize.intValue());
        NdkSupport.SetLongValue(nSize, byReaded);
        return 0;
    }

    private static SpecReadMultipleBlocks ISO15693_CreateTAReadMultipleBlocks(SpecTagAccessSet hTagAccessSet, boolean readSecSta, int blkAddr, int numOfBlksToRead) {
        SpecReadMultipleBlocks p = SpecReadMultipleBlocks.Create();
        if (p != null) {
            p.m_reqReadSecSta = readSecSta;
            p.m_reqStartAddr = blkAddr;
            p.m_reqNumBlkToRead = numOfBlksToRead;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    private static int ISO15693_ParseGetSystemInfoResult(SpecGetSysInfor tagAccess, byte[] uid, byte[] dsfid, byte[] afi, long[] blkSize,long[] numOfBloks, byte[] icRef) {
        SpecGetSysInfor p = tagAccess;
        if (p == null) return -3;
        try {
            if (uid != null) {
                int byCpy = 8;
                if (uid.length < byCpy) byCpy = uid.length;
                System.arraycopy(p.m_respUID, 0, uid, 0, byCpy);
            }
            if (dsfid != null)
            {
                dsfid[0]=p.m_respDSFID;
                //NdkSupport.SetByteValue(dsfid[0], p.m_respDSFID);
            }
            if (afi != null)
            {
                afi[0]=p.m_respAFI;
                //NdkSupport.SetByteValue(afi[0], p.m_respAFI);
                //System.arraycopy(p.m_respAFI,0,afi,0,1);
            }
            if (blkSize != null) {
                long blkSizeTmp = p.m_respSizeOfBlock;
                if (blkSizeTmp < 0L) blkSizeTmp += 256L;
                blkSize[0]=blkSizeTmp;
               // NdkSupport.SetLongValue(blkSize[0], blkSizeTmp);
            }
            if (numOfBloks != null)
            {
                numOfBloks[0]=p.m_respTotalBlockNum;
                //System.arraycopy( p.m_respTotalBlockNum,0,numOfBloks,0,1);
                //NdkSupport.SetLongValue(numOfBloks[0], p.m_respTotalBlockNum);
            }
            if (icRef != null)
            {
                icRef[0]=p.m_respICRef;
                //System.arraycopy( p.m_respICRef,0,icRef,0,1);
                //NdkSupport.SetByteValue(icRef[0], p.m_respICRef);
            }
        } catch (Exception e) {
            return -34;
        }
        return 0;
    }

    private static SpecConnPrmsISO15693 ISO15693_CreateConnectParam(long tagtype, byte address_mode, byte[] uid) {
        SpecConnPrmsISO15693 pConnParam = SpecConnPrmsISO15693.Create();
        if (pConnParam == null) return null;
        pConnParam.m_TagId = tagtype;
        pConnParam.m_AddrMode = address_mode;
        if (address_mode != 0 && uid != null) System.arraycopy(uid, 0, pConnParam.m_UID, 0, 8);
        return pConnParam;
    }

    public static SpecGetSysInfor ISO15693_CreateTAGetTagInfor(SpecTagAccessSet hTagAccessSet) {
        SpecGetSysInfor p = SpecGetSysInfor.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }



    private static SpecLockMultipleBlocks ISO15693_CreateTALockMultipleBlocks(SpecTagAccessSet hTagAccessSet, int blkAddr, int numOfBlks) {
        SpecLockMultipleBlocks p = SpecLockMultipleBlocks.Create();
        if (p != null) {
            p.m_reqStartBlock = blkAddr;
            p.m_reqNumOfBlock = numOfBlks;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    private static SpecWriteDSFID ISO15693_CreateTAWriteDSFID(SpecTagAccessSet hTagAccessSet, byte dsfid) {
        SpecWriteDSFID p = SpecWriteDSFID.Create();
        if (p != null) {
            p.m_DSFID = dsfid;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }



    private static SpecLockDSFID ISO15693_CreateTALockDSFID(SpecTagAccessSet hTagAccessSet) {
        SpecLockDSFID p = SpecLockDSFID.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }



    private static SpecWriteAFI ISO15693_CreateTAWriteAFI(SpecTagAccessSet hTagAccessSet, byte afi) {
        SpecWriteAFI p = SpecWriteAFI.Create();
        if (p != null) {
            p.m_AFI = afi;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }


    private static SpecLockAFI ISO15693_CreateTALockAFI(SpecTagAccessSet hTagAccessSet) {
        SpecLockAFI p = SpecLockAFI.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }



    private static SpecEnableEAS NXPICODESLI_CreateTAEableEAS(SpecTagAccessSet hTagAccessSet) {
        SpecEnableEAS p = SpecEnableEAS.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }



    private static SpecDisableEAS NXPICODESLI_CreateTADisableEAS(SpecTagAccessSet hTagAccessSet) {
        SpecDisableEAS p = SpecDisableEAS.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }


    private static SpecLockEAS NXPICODESLI_CreateTALockEAS(SpecTagAccessSet hTagAccessSet) {
        SpecLockEAS p = SpecLockEAS.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }



    private static SpecEASCheck NXPICODESLI_CreateTAEASCheck(SpecTagAccessSet hTagAccessSet) {
        SpecEASCheck p = SpecEASCheck.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    private static int NXPICODESLI_ParseEASCheckResult(SpecEASCheck tagAccess, Byte EASFlag) {
        SpecEASCheck p = tagAccess;
        if (p == null) return -3;
        if (EASFlag != null) NdkSupport.SetByteValue(EASFlag, p.m_respFlag);
        return 0;
    }



    private static SpecGetRandom NXPICODESLI_CreateTAGetRandaom(SpecTagAccessSet hTagAccessSet) {
        SpecGetRandom p = SpecGetRandom.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    private static int NXPICODESLI_ParseGetRandomResult(SpecGetRandom tagAccess, int[] random) {
        SpecGetRandom p = tagAccess;
        if (p == null) return -3;
        if (random == null || random.length <= 1) return -34;
        random[0] = p.m_respRandom;
        return 0;
    }



    private static SpecSetPassword NXPICODESLI_CreateTASetPassword(SpecTagAccessSet hTagAccessSet, byte pwdNo, int random, long pwd) {
        SpecSetPassword p = SpecSetPassword.Create();
        if (p != null) {
            p.m_reqPwd = pwd;
            p.m_reqPwdNo = pwdNo;
            p.m_reqRandom = random;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }



    private static SpecWritePassword NXPICODESLI_CreateTAWritePassword(SpecTagAccessSet hTagAccessSet, byte pwdNo, long pwd) {
        SpecWritePassword p = SpecWritePassword.Create();
        if (p != null) {
            p.m_reqPwd = pwd;
            p.m_reqPwdNo = pwdNo;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    public int NXPICODESLI_WritePassword(byte pwdNo, long pwd) {
        SpecWritePassword tagAccess = NXPICODESLI_CreateTAWritePassword(null, pwdNo, pwd);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }

    private static SpecLockPassword NXPICODESLI_CreateTALockPassword(SpecTagAccessSet hTagAccessSet, byte pwdNo) {
        SpecLockPassword p = SpecLockPassword.Create();
        if (p != null) {
            p.m_reqPwdNo = pwdNo;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }



    private static SpecPasswordProtect NXPICODESLI_CreateTAPasswordProtect(SpecTagAccessSet hTagAccessSet, byte bandType) {
        SpecPasswordProtect p = SpecPasswordProtect.Create();
        if (p != null) {
            p.m_reqBandType = bandType;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    public int NXPICODESLI_PasswordProtect(byte bandType) {
        if (bandType != 0 && bandType != 1) return -3;
        SpecPasswordProtect tagAccess = NXPICODESLI_CreateTAPasswordProtect(null, bandType);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }

    private static SpecGetRandomAndSetPwd NXPICODESLI_CreateTAGetRandomAndSetPassword(SpecTagAccessSet hTagAccessSet, byte pwdNo, long pwd) {
        SpecGetRandomAndSetPwd p = SpecGetRandomAndSetPwd.Create();
        if (p != null) {
            p.m_reqPwd = pwd;
            p.m_reqPwdNo = pwdNo;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    public int NXPICODESLI_GetRandomAndSetPassword(byte pwdNo, long pwd) {
        SpecGetRandomAndSetPwd tagAccess = NXPICODESLI_CreateTAGetRandomAndSetPassword(null, pwdNo, pwd);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }

    private static SpecWriteEASID NXPICODESLI_CreateTAWriteEASID(SpecTagAccessSet hTagAccessSet, int EASID) {
        SpecWriteEASID p = SpecWriteEASID.Create();
        if (p != null) {
            p.m_reqEASID = EASID;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    public int NXPICODESLI_WriteEASID(int EASID) {
        SpecWriteEASID tagAccess = NXPICODESLI_CreateTAWriteEASID(null, EASID);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }

    private static SpecGetNxpSysInfo NXPICODESLI_CreateTAGetNxpSysInfo(SpecTagAccessSet hTagAccessSet) {
        SpecGetNxpSysInfo p = SpecGetNxpSysInfo.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    private static int NXPICODESLI_ParseGetNxpSysInfoResult(SpecGetNxpSysInfo tagAccess, byte[] PPPointer, byte[] PPConditions, byte[] lockBits, long[] featureFlags) {
        SpecGetNxpSysInfo p = tagAccess;
        if (p == null) return -3;
        if (PPPointer != null && PPPointer.length >= 1) PPPointer[0] = p.m_respPPPointer;
        if (PPConditions != null && PPConditions.length >= 1)
            PPConditions[0] = p.m_respPPConditions;
        if (lockBits != null && lockBits.length >= 1) lockBits[0] = p.m_respLockBits;
        if (featureFlags != null) featureFlags[0] = p.m_respFeatureFlags;
        return 0;
    }

    public int NXPICODESLI_GetNxpSysInfo(byte[] PPPointer, byte[] PPConditions, byte[] lockBits, long[] featureFlags) {
        int iret = -1;
        SpecGetNxpSysInfo tagAccess = NXPICODESLI_CreateTAGetNxpSysInfo(null);
        if (tagAccess == null) return -6;
        iret = this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
        if (iret != 0) return iret;
        return NXPICODESLI_ParseGetNxpSysInfoResult(tagAccess, PPPointer, PPConditions, lockBits, featureFlags);
    }

    private static SpecReadSignature NXPICODESLI_CreateTAReadSignature(SpecTagAccessSet hTagAccessSet) {
        SpecReadSignature p = SpecReadSignature.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    private static int NXPICODESLI_ParseReadSignatureResult(SpecReadSignature tagAccess, byte[] signature) {
        SpecReadSignature p = tagAccess;
        if (p == null) return -3;
        if (signature == null || signature.length < 32) return -12;
        System.arraycopy(p.m_respSignature, 0, signature, 0, 32);
        return 0;
    }

    public int NXPICODESLI_ReadSignature(byte[] signature) {
        int iret = -1;
        SpecReadSignature tagAccess = NXPICODESLI_CreateTAReadSignature(null);
        if (tagAccess == null) return -6;
        iret = this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
        if (iret != 0) return 0;
        return NXPICODESLI_ParseReadSignatureResult(tagAccess, signature);
    }

    private static SpecEnable64BitsPwd NXPICODESLI_CreateTAEnable64BitPwd(SpecTagAccessSet hTagAccessSet) {
        SpecEnable64BitsPwd p = SpecEnable64BitsPwd.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }



    private static SpecProtectPage NXPICODESLI_CreateTAProtectPage(SpecTagAccessSet hTagAccessSet, byte PPPointer, byte protSta) {
        SpecProtectPage p = SpecProtectPage.Create();
        if (p != null) {
            p.m_reqPPPointer = PPPointer;
            p.m_reqPPCondition = protSta;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    public int NXPICODESLI_ProtectPage(byte PPPointer, byte protSta) {
        SpecProtectPage tagAccess = NXPICODESLI_CreateTAProtectPage(null, PPPointer, protSta);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }

    private static SpecLockPageProtection NXPICODESLI_CreateTALockPageProtection(SpecTagAccessSet hTagAccessSet, byte pageAddr) {
        SpecLockPageProtection p = SpecLockPageProtection.Create();
        if (p != null) {
            p.m_reqPageAddr = pageAddr;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    public int NXPICODESLI_LockPageProtection(byte pageAddr) {
        SpecLockPageProtection tagAccess = NXPICODESLI_CreateTALockPageProtection(null, pageAddr);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }

    private static SpecDestroy NXPICODESLI_CreateTADestroy(SpecTagAccessSet hTagAccessSet, long pwd) {
        SpecDestroy p = SpecDestroy.Create();
        if (p != null) {
            p.m_reqPwd = pwd;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    public int NXPICODESLI_Destroy(long pwd) {
        SpecDestroy tagAccess = NXPICODESLI_CreateTADestroy(null, pwd);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }

    private static SpecEnablePrivacy NXPICODESLI_CreateTAEnblePrivacy(SpecTagAccessSet hTagAccessSet, long pwd) {
        SpecEnablePrivacy p = SpecEnablePrivacy.Create();
        if (p != null) {
            p.m_reqPwd = pwd;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    public int NXPICODESLI_EnblePrivacy(long pwd) {
        SpecEnablePrivacy tagAccess = NXPICODESLI_CreateTAEnblePrivacy(null, pwd);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }

    private SpecPresetCounter NXPICODESLI_CreateTAPresetCounter(SpecTagAccessSet hTagAccessSet, int initCnt, boolean enReadPwdProtect) {
        SpecPresetCounter p = SpecPresetCounter.Create();
        if (p != null) {
            p.m_reqInitCnt = initCnt;
            p.m_reqReadPwdProtect = enReadPwdProtect;
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    public int NXPICODESLI_PresetCounter(int initCnt, boolean enReadPwdProtect) {
        SpecPresetCounter tagAccess = NXPICODESLI_CreateTAPresetCounter(null, initCnt, enReadPwdProtect);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }

    private static SpecIncrementCounter NXPICODESLI_CreateTAIncrementCounter(SpecTagAccessSet hTagAccessSet) {
        SpecIncrementCounter p = SpecIncrementCounter.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    public int NXPICODESLI_IncrementCounter() {
        SpecIncrementCounter tagAccess = NXPICODESLI_CreateTAIncrementCounter(null);
        if (tagAccess == null) return -6;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }

    private static SpecReset ISO15693_CreateTAReset(SpecTagAccessSet hTagAccessSet) {
        SpecReset p = SpecReset.Create();
        if (p != null) {
            SpecTagAccessSet pSet = hTagAccessSet;
            if (pSet != null) pSet.AddTagAccess(p);
        }
        return p;
    }

    public int ISO15693_Reset() {
        SpecReset tagAccess = ISO15693_CreateTAReset(null);
        if (tagAccess == null) return -6;
        if (this.m_reader == null)
            return -1;
        return this.m_reader.PICC_Access(this.hTag.getTagHandle(), tagAccess);
    }
}
